﻿
if (typeof (VOfficeHelper) == 'undefined')
    VOfficeHelper = {};

VH = VOfficeHelper; //short hand

/* 
Kiểm tra thông tin user
Thông tin user được ghi xuống client bằng model AppInfo bao gồm:
- UserId là id của user đó
- UserName tên đăng nhập
- FullName tên đầy đủ của người dùng đó
- Depts là list phòng ban mà người đó trực thuộc [{Key = id_phòng_ban, Value = tên_phòng_ban}]
- CurrentDept là phòng ban hiện tại của người dùng {Key = id_phòng_ban, Value = tên_phòng_ban}
Các hàm dưới đây giúp mình lấy ra thông tin của người dùng tốt hơn
*/
VOfficeHelper.ValidateAppInfo = function () {
    ///<summary>
    /// Kiểm tra xem có thông tin người dùng(Đang đăng nhập) ở client không
    ///</summary>
    if (typeof (appinfo) == "undefined" || !appinfo) {
        return false;
    }
    return true;
};
VOfficeHelper.getDeptId = function () {
    if (typeof (appinfo) == "undefined" || !appinfo) {
        return null;
    }
    return appinfo.CurrentDept.Key;
};
/*
Lấy ra thông về trình duyệt hiện tại, để loại bỏ console.log nếu trình duyệt không hỗ trợ 
*/
VOfficeHelper.isIE = (window.navigator.userAgent.indexOf('MSIE') != -1);
VOfficeHelper.compatibleMode = function () {
    /// <summary>
    /// ghi đè hàm console.log trên ie
    /// </summary>
    if (VOfficeHelper.isIE) {
        if (typeof (console) == 'undefined' || typeof (console.log) == 'undefined') {
            window.console = { log: function () { } };
        }
        else {
            console.log = function () { };
        }
    }
};

/* 
Setup để ghi đè header cho mỗi ajax request, đưa token vào để chống csrf 
*/
var ajaxsetup = (function ($) {
    ///<summary>
    /// Chống tấn công qua csrf, redirect khi không authen được controller cho các ajax request
    ///</summary>
    $.ajaxSetup({
        beforeSend: function (jqXHR) {
            jqXHR.setRequestHeader("__RequestVerificationToken", window.__RequestVerificationToken);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            if (jqXHR.status == 403) {
                alert(jqXHR.responseText);
                window.location = '/Home/LogOut';
            }
        }
    });
})(jQuery);

/*
Lấy giá trị token từ input trình duyệt đưa vào đối tượng window để lấy giá trị thuận tiện hơn
*/
VOfficeHelper.tokenVerification = function () {
    ///<summary>
    /// Hàm lấy thông tin từ input verificationtoken để đưa vào biến window, sử dụng cho việc lấy giá trị ra sau này
    ///</summary>
    window.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
};

/*
Gọi hàm luôn để thực thi nếu cần cosole để debug trên ie thì có thể bỏ hàm này đi
*/
VOfficeHelper.compatibleMode();

/*
Sinh html để nhúng vào trang web hỗ trợ việc chuyển ngôn ngữ của người dùng
*/
VOfficeHelper.languageSelector = function (parameters) {
    /// <summary>
    /// hiển thị control chọn ngôn ngữ
    /// </summary>
    var $selectorObject = $('#lang-selector');
    if ($selectorObject.length == 0) {
        var langList = [
                '<div id="lang-selector">',
                    '<ul>',
                        '<li>',
                            '<a href="javascript:void(0)" data-value="vi-VN">Tiếng Việt</a>',
                        '</li>',
                        '<li>',
                            '<a href="javascript:void(0)" data-value="en-US">English(US)</a>',
                        '</li>',
                        '<li>',
                            '<a href="javascript:void(0)" data-value="lo-LA" style="font-family:VangViengMXRegular">ລາວ</a>',
                        '</li>',
                    '</ul>',
                '</div>'
        ].join('');
        $('body').append(langList);
        $selectorObject = $('#lang-selector');
        var $a = $selectorObject.find('a');
        $a.die('click');
        $a.live("click", VOfficeHelper.languageChanged);
        if (!$.cookie("_culture")) {
            $.cookie("_culture", "vi-VN", { expires: 365, path: '/' });
        }
    }
};

/*
Sự kiện khi người dùng muốn thay đổi ngôn ngữ
*/
VOfficeHelper.languageChanged = function (event) {
    /// <summary>
    /// thực hiện sự kiện khi người dùng chọn ngôn ngữ
    /// </summary>
    var $target = $(event.currentTarget);
    var value = $target.attr('data-value');
    if (!!value) {
        $.cookie("_culture", value, { expires: 365, path: '/' });
        window.location.reload(); // reload 
    }
};

/* KHI UNG DUNG DA DUOC TAI */
$(document).ready(function () {
    VH.languageSelector();
    VH.tokenVerification();
    //ẩn chọn ngôn ngữ khi scroll chuột
    var $lang = $('#lang-selector');
    if ($lang && $lang.length > 0) {
        $(window).bind('scroll', function (event) {
            if ($(this).scrollTop() > 0) {
                $lang.css('opacity', '0.1').css('filter', 'alpha(opacity = 10)');
            } else {
                $lang.css('opacity', '1').css('filter', 'alpha(opacity = 100)');
            }
            return true;
        });
    }
});

/* 
Sinh guid 
*/
VOfficeHelper.NewGuid = function () {
    ///<summary>
    /// Tạo giá trị guid bằng code js
    ///</summary>
    'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
        return v.toString(16);
    });
};

VOfficeHelper.MakeOption = function (keyValueList, selected) {
    /// <summary>
    /// Tạo ra các option cho thẻ select từ dữ liệu truyền vào
    /// </summary>
    var html = "";
    if (!!keyValueList && keyValueList.length > 0) {
        _.each(keyValueList, function (item) {
            html = html + ['<option value = "',
                item.Key,
                '"',
                parseFloat(item.Key) == parseFloat(selected) ? 'selected = "selected"' : '',
                '>',
                item.Value,
                '</option>'].join('');
        });
    }
    return html;
};

VOfficeHelper.ConfirmBox = function (content, yesButtonName, noButtonName, yesCallback, noCallBack, title) {
    ///<summary>
    /// Tạo ra confirm box 
    ///  <param name="content">nội dung của box</param> 
    ///  <param name="yesButtonName">tên của nút thực hiện code chính (thường là nút thực hiện như yes delete)</param> 
    ///  <param name="noButtonName">tên của nút thực hiện nút phụ (thường là từ chối no delete)</param>
    ///  <param name="yesCallback">hàm sẽ gọi sau khi chọn yes-button</param>
    ///  <param name="noCallBack">hàm sẽ gọi sau khi chọn no-button</param>    
    ///</summary>
    var $dialogConfirm = $('#dialog-confirm');
    if ($dialogConfirm.length == 0) {
        $('body').append('<div id="dialog-confirm" style="display:none" />');
        $dialogConfirm = $('#dialog-confirm');
    }
    $dialogConfirm.html(content);
    $dialogConfirm.dialog({
        resizable: false,
        height: 'auto',
        modal: true,
        buttons: {
            yes: {
                text: yesButtonName,
                click: function () {
                    if (!!yesCallback) {
                        yesCallback();
                    }
                    $(this).dialog("close");
                }
            },
            no: {
                text: noButtonName,
                click: function () {
                    if (!!noCallBack) {
                        noCallBack();
                    }
                    $(this).dialog("close");
                }
            }
        }
    });
    $dialogConfirm.dialog('option', 'title', title);
};

VOfficeHelper.MessageBox = function (message, closeCallBack) {
    /// <summary>
    /// Bật thông báo
    /// <param name="message">Nội dung thông báo</param>
    /// <param name="closeCallBack">Event thực hiện khi dialog đóng</param>
    /// </summary>
    var $dialog = $('#message-box');
    if (!$dialog || $dialog.length == 0) {
        $('body').append('<div id="message-box"/>');
        $dialog = $('#message-box');
    }
    $dialog.html(message).dialog({
        modal: true,
        height: 'auto',
        width: 400,
        title: jsResources.lang.DialogModelTitle,
        buttons: {
            ok: {
                text: jsResources.lang.DialogModelButton,
                click: function () {
                    $(this).dialog("close");
                }
            }
        },
        close: closeCallBack
    });
};

VOfficeHelper.ShowControllerPopupTree = function () {
    ///<summary>
    /// Hiển thị ra cây phòng ban chọn
    /// <param name="callBackAfterSelected">Phải truyền vào hàm để sau khi chọn</param>
    /// <returns type="">window.SelectedDeptName và window.SelectedDeptId </returns>
    /// </summary>
    window.SelectedDeptId = null;
    window.SelectedDeptName = null;
    var $deptDialog = $('#dept-tree-dialog');
    var $body = $('body');
    if ($deptDialog.length == 0) {
        $('body').append('<div id="dept-tree-dialog" style="display:none"/>');
        $deptDialog = $('#dept-tree-dialog');
    }
    $deptDialog.load('/Common/controller_action_popup', function (data) {
        $deptDialog.dialog({
            autoOpen: true,
            show: "fade",
            hide: "fade",
            modal: true,
            height: 600,
            width: 600,
            'z-index': 1003,
            'title': jsResources.lang.DeptTreeDialogTitle,
            open: function (event, ui) {
            },
            close: function (event, ui) {
            }
        });
    });
};

VOfficeHelper.ShowDeptTree = function (callBackAfterSelected) {
    ///<summary>
    /// Hiển thị ra cây phòng ban chọn
    /// <param name="callBackAfterSelected">Phải truyền vào hàm để sau khi chọn</param>
    /// <returns type="">window.SelectedDeptName và window.SelectedDeptId </returns>
    /// </summary>
    window.SelectedDeptId = null;
    window.SelectedDeptName = null;
    var $deptDialog = $('#dept-tree-dialog');
    var $body = $('body');
    if ($deptDialog.length == 0) {
        $('body').append('<div id="dept-tree-dialog" style="display:none"/>');
        $deptDialog = $('#dept-tree-dialog');
    }
    $deptDialog.load('/common/DeptTree', function (data) {
        $deptDialog.dialog({
            autoOpen: true,
            show: "fade",
            hide: "fade",
            modal: true,
            height: 600,
            width: 600,
            'z-index': 1003,
            'title': jsResources.lang.DeptTreeDialogTitle,
            open: function (event, ui) {
            },
            close: function (event, ui) {
            }
        });
    });
    //bin sự kiện để trigger ở trong trang
    $body.unbind('closeSDT');
    $body.bind('closeSDT', function () {
        if (!!callBackAfterSelected) {
            $deptDialog.bind('dialogclose', callBackAfterSelected);
        }
        $deptDialog.dialog('close');
    });
};

VOfficeHelper.ShowDeptTreeWithUser = function (callBackAfterSelected) {
    /// <summary>
    /// Hiển thị danh sách chọn phòng ban, rồi chọn người dùng
    /// <param name="callBackAfterSelected">Hàm gọi sau khi chọn</param>
    /// <returns type="">
    /// window.SelectedDeptId là id của phòng ban đã chọn
    /// window.SelectedDeptName là tên phòng ban đã chọn
    /// window.SelectedUsers là array [] chứa các object json gồm UserId và UserName của các User được chọn
    /// </returns>
    /// </summary>
    window.SelectedDeptId = null;
    window.SelectedDeptName = null;
    window.SelectedUsers = null;
    var $deptDialog = $('#dept-tree-dialog');
    var $body = $('body');
    if ($deptDialog.length == 0) {
        $body.append('<div id="dept-tree-dialog" style="display:none"/>');
        $deptDialog = $('#dept-tree-dialog');
    }
    $deptDialog.load('/common/DeptTreeWithUser', function (data) {
        $deptDialog.dialog({
            autoOpen: true,
            show: "fade",
            hide: "fade",
            modal: true,
            height: 600,
            width: 680,
            'z-index': 1003,
            'title': jsResources.lang.DeptTreeDialogWithUserTitle,
            open: function (event, ui) {
            },
            close: function (event, ui) {
            }
        });
    });
    //bin sự kiện để trigger ở trong trang
    $body.unbind('closeSDWU');
    $body.bind('closeSDWU', function () {
        if (!!callBackAfterSelected) {
            callBackAfterSelected();
        }
        $deptDialog.dialog("close");
    });
};

VOfficeHelper.ShowLibrary = function (callBackAfterSelected) {
    /// <summary>
    /// Bật dialog chọn văn bản trong thư viện
    /// <param name="callBackAfterSelected">Hàm được gọi sau khi chọn</param>
    /// </summary>
    window.SelectedLibItemId = null;
    window.SelectedLibItemName = null;
    var $libDialog = $('#library-list-dialog');
    var $body = $('body');
    if ($libDialog.length == 0) {
        $body.append('<div id="library-list-dialog" style="display:none"/>');
        $libDialog = $('#library-list-dialog');
    }
    $libDialog.load('/common/libray_items', function (data) {
        $libDialog.dialog({
            autoOpen: true,
            show: "fade",
            hide: "fade",
            modal: true,
            height: 'auto',
            width: 600,
            'z-index': 1003,
            'title': jsResources.lang.LibraryDialogTitle,
            open: function (event, ui) {
            },
            close: function (event, ui) {
            }
        });
    });
    //bin sự kiện để trigger ở trong trang
    $body.unbind('closeSL');
    $body.bind('closeSL', function () {
        if (!!callBackAfterSelected) {
            $libDialog.bind('dialogclose', callBackAfterSelected);
        }
        $libDialog.dialog('close');
    });
};

VOfficeHelper.ShowOfficePartner = function (allowMulti, callBackAfterSelected) {
    ///<summary>
    /// Hiển thị ra bảng chọn phòng ban gửi công văn
    ///</summary>
    window.SelectedLibItemId = null;
    window.SelectedLibItemName = null;
    var $partnerDialog = $('#partner-list-dialog');
    var $body = $('body');
    if ($partnerDialog.length == 0) {
        $body.append('<div id="partner-list-dialog" style="display:none"/>');
        $partnerDialog = $('#partner-list-dialog');
    }
    $partnerDialog.load('/common/select_office_partner/?allowMulti=' + (!allowMulti ? false : allowMulti) + '&nocache=' + (new Date()).toJSON(), function (data) {
        $partnerDialog.dialog({
            autoOpen: true,
            show: "fade",
            hide: "fade",
            modal: true,
            height: 'auto',
            width: 600,
            'z-index': 1003,
            'title': jsResources.lang.OfficePartnerDialogTitle,
            open: function (event, ui) {
            },
            close: function (event, ui) {
            }
        });
    });
    //bin sự kiện để trigger ở trong trang
    $body.unbind('closeSOP');
    $body.bind('closeSOP', function () {
        if (!!callBackAfterSelected) {
            callBackAfterSelected();
        }
        $partnerDialog.dialog('close');
    });
};

VOfficeHelper.ShowFlowDetails = function (flowId, callBackAfterSelected, distroyCallBack) {
    ///<summary>
    /// Hiển thị chi tiết luồng để lựa chọn 
    ///</summary>
    window.SelectedFlowId = null;
    var $flowDialog = $('#flow-details-dialog');
    var $body = $('body');
    if ($flowDialog.length == 0) {
        $body.append('<div id="flow-details-dialog" style="display:none"/>');
        $flowDialog = $('#flow-details-dialog');
    }
    $flowDialog.dialog({
        autoOpen: true,
        show: "fade",
        hide: "fade",
        modal: true,
        height: $(window).height() - 20,
        width: $(window).width() - 20,
        'z-index': 1003,
        'title': jsResources.lang.FlowDetailsDialogTitle,
        open: function (event, ui) {
        },
        close: function (event, ui) {
        }
    });
    $flowDialog.html('');
    $flowDialog.load('/common/show_flow_details/?flowId=' + flowId + '&nocache=' + (new Date()).toJSON(), function (data) {
    });
    if (distroyCallBack) {
        window.AfterSelectFlow = null;
    }
    if (callBackAfterSelected) {
        window.AfterSelectFlow = callBackAfterSelected;
    }
    //bin sự kiện để trigger ở trong trang
    $body.unbind('closeFD');
    $body.bind('closeFD', function () {
        if (!!window.AfterSelectFlow) {
            window.AfterSelectFlow();
        }
        $flowDialog.dialog('close');
    });
};

VOfficeHelper.DateUtility = (function () {
    /// <summary>
    /// Cách gọi VH.DateUtility.FixDates(o);//với o là object json chứa datatime cần fix
    /// sau khi gọi hàm thì sử dụng o bình thường
    /// </summary>
    var fn, recurse, dateRegex;
    dateRegex = /^\/Date\(\d+\)\/$/;
    fn = {
        GetPseudoJsonDate: function (s) {
            if (typeof s === 'string')
                return new Date(parseInt(s.substring(6)));
            else
                throw new Error('GetPseudoJsonDate expects a string parameter.');
        },
        /*
        Hàm để fix lại ngày tháng cho dữ liệu trả về từ server
        */
        FixDates: function (o) {
            if (typeof o === 'object')
                recurse(o);
            else
                throw new Error('FixDates expects an object');
        }
    }; // end fn
    recurse = function (o) {
        var x;
        for (x in o) {
            if (typeof o[x] === 'string' && o[x].match(dateRegex))
                o[x] = fn.GetPseudoJsonDate(o[x]);
            else if (typeof o[x] === 'object')
                recurse(o[x]);
        }
    }; // end function recurse
    return fn;
})();  // end DateUtility;

VOfficeHelper.toJsonArray = function (arrayOfObject) {
    /// <summary>
    /// Convert một mảng đối tượng thành 1 mảng json tương ứng
    /// <param name="arrayOfObject">Mảng của các object</param>
    /// </summary>
    if (!arrayOfObject) {
        return null;
    }
    if (arrayOfObject.length == 0) return [];
    var result = [];
    for (var i = 0; i < arrayOfObject.length; i++) {
        result.push(arrayOfObject[i].toJSON());
    }
    return result;
};

/* 
Append ham vao array 
*/
Array.prototype.toJsonArray = function () {
    /// <summary>
    /// Convert một mảng đối tượng thành 1 mảng json tương ứng
    /// <param name="arrayOfObject">Mảng của các object</param>
    /// </summary>
    return VH.toJsonArray(this);
};

if (typeof String.prototype.startsWith != 'function') {
    String.prototype.startsWith = function (str) {
        ///<summary>
        /// kiểm tra chuỗi có bắt đầu bằng chuỗi truyền vào
        ///</summary>
        return str.length > 0 && this.substring(0, str.length) === str;
    };
};

if (typeof String.prototype.endsWith != 'function') {
    String.prototype.endsWith = function (str) {
        ///<summary>
        /// Kiểm tra một chuỗi có kết thúc bằng chuỗi truyền vào
        ///</summary>
        return str.length > 0 && this.substring(this.length - str.length, this.length) === str;
    };
};

VOfficeHelper.htmlEncode = function (value) {
    /// <summary>
    /// encode chuỗi html
    /// </summary>
    return $('<div/>').text(value).html();
};

VOfficeHelper.htmlDecode = function (value) {
    /// <summary>
    /// decode chuỗi html
    /// </summary>
    return $('<div/>').html(value).text();
};

VOfficeHelper.convertToServerDate = function (inputDate) {
    ///<summary>
    /// Biến thời gian nhập vào thành thời gian iso cho server. Cần file date.format.js
    /// <param name="inputDate">Thời gian truyền vào</param>
    ///</summary>
    if (jsResources.lang.ValidDate) {
        var bits = inputDate.match(/([0-9]+)/gi), str;
        if (!bits)
            return null;
        if (jsResources.lang.ValidDate.toLowerCase().startsWith("d")) {
            str = bits[1] + '/' + bits[0] + '/' + bits[2];
        } else {
            str = bits[0] + '/' + bits[1] + '/' + bits[2];
        }
        var date = new Date(str);
        if (!/Invalid|NaN/.test(date)) {
            return dateFormat(date, "isoDateTime");
        }
        return null;
    } else {
        return null;
    }
};

/* 
Viết thêm các luật validate dữ liệu ở đây
*/
if (typeof ($.validator) != 'undefined') {
    $.validator.addMethod(
        'validDate',
        function (value, element) {
            var bits = value.match(/([0-9]+)/gi), str;
            if (!bits)
                return this.optional(element) || false;
            if (jsResources.lang.ValidDate.toLowerCase().startsWith("d")) {
                str = bits[1] + '/' + bits[0] + '/' + bits[2];
            } else {
                str = bits[0] + '/' + bits[1] + '/' + bits[2];
            }
            return this.optional(element) || !/Invalid|NaN/.test(new Date(str));
        },
        ""//jsResources.RequiredValidDate()
    );

    $.validator.addMethod(
        'lessThanNow',
        function (value, element) {
            var bits = value.match(/([0-9]+)/gi), str;
            if (!bits)
                return this.optional(element) || false;
            if (jsResources.lang.ValidDate.toLowerCase().startsWith("d")) {
                str = bits[1] + '/' + bits[0] + '/' + bits[2];
            } else {
                str = bits[0] + '/' + bits[1] + '/' + bits[2];
            }
            return this.optional(element) || new Date(str) < new Date();
        },
        ""//jsResources.lang.RequiredDateLessThanNow
    );
}

/*
Lấy ra culture hiện tại, chỉnh lại calendar
*/
if (typeof (Globalize) != "undefined" && typeof (Globalize.cultures) != 'undefined') {
    Globalize.culture = Globalize.cultures[$.cookie("_culture")];
    if (!Globalize.culture) {
        Globalize.culture = Globalize.cultures[$.cookie("vi-VN")];
    }

    //setup calendar
    if (typeof ($.datepicker) != 'undefined') {//nếu có control calendar
        $.datepicker.regional[''] = {
            closeText: jsResources.lang.DatePickerDone, // Display text for close link
            prevText: jsResources.lang.DatePickerPrev, // Display text for previous month link
            nextText: jsResources.lang.DatePickerNext, // Display text for next month link
            currentText: jsResources.lang.DatePickerToday, // Display text for current month link
            monthNames: Globalize.culture.calendars.standard.months.names, // Names of months for drop-down and formatting
            monthNamesShort: Globalize.culture.calendars.standard.months.namesAbbr, // For formatting
            dayNames: Globalize.culture.calendars.standard.days.names, // For formatting
            dayNamesShort: Globalize.culture.calendars.standard.days.namesAbbr, // For formatting
            dayNamesMin: Globalize.culture.calendars.standard.days.namesShort, // Column headings for days starting at Sunday
            weekHeader: 'Wk', // Column header for week of the year
            dateFormat: jsResources.lang.DateFormat, // See format options on parseDate
            firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
            isRTL: false, // True if right-to-left language, false if left-to-right
            showMonthAfterYear: false, // True if the year select precedes month, false for month then year
            yearSuffix: '' // Additional text to append to the year in the month headers
        };
        $.datepicker.setDefaults($.datepicker.regional['']);
    }
}